home *** CD-ROM | disk | FTP | other *** search
/ Shareware Grab Bag / Shareware Grab Bag.iso / 007 / lpmac1.arc / MACROS.DOC < prev    next >
Text File  |  1987-03-03  |  25KB  |  643 lines

  1.  
  2.  
  3.  
  4.  
  5.  
  6.  
  7.           Documentation for MACROS.MLB                               Page 1
  8.  
  9.  
  10.                                   TABLE OF CONTENTS
  11.  
  12.  
  13.           INTRODUCTION . . . . . . . . . . . . . . . . . . . . . . . .    2
  14.  
  15.           CONVENTIONS, OPENING MACROS AND CLOSING MACROS . . . . . . .    3
  16.                LISTING CONTROL . . . . . . . . . . . . . . . . . . . .    3
  17.                OUT_UNNECESSARY_LONG_COMMENTS - Closing summary macro .    3
  18.                BLANK MACRO ARGUMENTS . . . . . . . . . . . . . . . . .    3
  19.                CONVENTIONS IN THIS DOCUMENTATION . . . . . . . . . . .    4
  20.  
  21.           A STRATEGY TO MINIMIZE THE NUMBER OF LONG JUMPS  . . . . . .    5
  22.  
  23.           JUMPS TO EXPLICIT LABELS . . . . . . . . . . . . . . . . . .    6
  24.                GENERAL . . . . . . . . . . . . . . . . . . . . . . . .    6
  25.                LJMP TARGET_LABEL, LONG - Unconditional jump to
  26.                     TARGET_LABEL.  . . . . . . . . . . . . . . . . . .    6
  27.                LCJMP CONDITION-1, TARGET_LABEL, LONG - Conditional
  28.                     jump to TARGET_LABEL.  . . . . . . . . . . . . . .    6
  29.                LJCXZ     TARGET_LABEL, LONG - Jump to TARGET_LABEL if
  30.                     register CX is zero. . . . . . . . . . . . . . . .    6
  31.                LLOOP CONDITION-3, TARGET_LABEL, LONG - Conditional and
  32.                     unconditional loops. . . . . . . . . . . . . . . .    6
  33.  
  34.           STRUCTURED MACROS  . . . . . . . . . . . . . . . . . . . . .    7
  35.                GENERAL . . . . . . . . . . . . . . . . . . . . . . . .    7
  36.                Jump to the beginning or the end of an "enclosing
  37.                     block" . . . . . . . . . . . . . . . . . . . . . .    8
  38.                BEGIN and END . . . . . . . . . . . . . . . . . . . . .    9
  39.                IF and IF - ELSE with one condition . . . . . . . . . .    9
  40.                IF and IF - ELSE with multiple AND conditions . . . . .   10
  41.                Repetition for a count  . . . . . . . . . . . . . . . .   11
  42.                WHILE . . . . . . . . . . . . . . . . . . . . . . . . .   12
  43.                REPEAT UNTIL  . . . . . . . . . . . . . . . . . . . . .   12
  44.                REPEAT FOREVER  . . . . . . . . . . . . . . . . . . . .   12
  45.  
  46.           OTHER MACROS . . . . . . . . . . . . . . . . . . . . . . . .   13
  47.                Multiple PUSH and POP . . . . . . . . . . . . . . . . .   13
  48.                Show the state of the Zero Flag in AL . . . . . . . . .   13
  49.                NOTZ - Toggle the Zero Flag . . . . . . . . . . . . . .   13
  50.                Call procedures which use a string whose OFFSET is in
  51.                     either BX or DX  . . . . . . . . . . . . . . . . .   13
  52.                Call a procedure which uses a File Control Block  . . .   14
  53.  
  54.  
  55.  
  56.  
  57.  
  58.  
  59.           Documentation for MACROS.MLB                               Page 2
  60.  
  61.  
  62.  
  63.           I.                         INTRODUCTION
  64.  
  65.                I based this collection of macros for MicroSoft MASM on
  66.           MACROS.MLB in the public domain file HERSHMAC.ARC, which Mark
  67.           Hersey of Hersey Micro Consulting, Inc. wrote.  I made enough
  68.           changes so that I can not claim that his work created any
  69.           problems you might find with it.
  70.  
  71.                HERSHMAC.ARC also includes the following files which define
  72.           symbolic constants:
  73.                     CHARS.MLB contains constant declarations for ASCII
  74.                characters.
  75.                     I8086.MLB contains constant declarations which are for
  76.                use with an 8086 assembler.
  77.                     MSDOS.MLB contains constant declarations which are for
  78.                use with Seattle Computer Products MS-DOS operating system. 
  79.                They seem useable for Microsoft's PC-DOS also.
  80.           I have tried to be sure that MACROS.MLB and these three files do
  81.           not depend on one another.  I have included them in this ARChive.
  82.  
  83.                Michael Abrash's article "Conditional-jump Macros" in the
  84.           February, 1987 issue of "PC Tech Journal" inspired the macros
  85.           which begin with the letter L and give various forms of jump and
  86.           loop instructions.
  87.  
  88.                Since I am placing these macros in the public domain, I am
  89.           not responsible for any bad things which they might do.
  90.  
  91.           Lew Paper
  92.           10:53 am on 3/1/87
  93.  
  94.  
  95.  
  96.  
  97.  
  98.           Documentation for MACROS.MLB                               Page 3
  99.  
  100.  
  101.  
  102.           II.      CONVENTIONS, OPENING MACROS AND CLOSING MACROS 
  103.  
  104.           A.  LISTING CONTROL
  105.  
  106.                MASM allows three kinds of listing for macro expansions. 
  107.           .LALL lists code and ";" comments; .XALL lists code only; .SALL
  108.           surpresses all listing.  The default is .XALL.
  109.  
  110.                MACROS.MLB uses the macro variable MACRO_EXPANSION_CONTROL
  111.           to specify which level you want.  If it is not defined, it
  112.           assumes .XALL, which is consistent with the MASM default.  Its
  113.           definitions are:
  114.                0 for .XALL (list code only)
  115.                1 for .SALL (surpress all listing)
  116.                2 for .LALL (list code and comments).
  117.                Any other value also gives .XALL.
  118.  
  119.                The macro SET_MACRO_EXPANSION actually sets MASM's listing
  120.           control according to to the value in MACRO_EXPANSION_CONTROL.
  121.  
  122.                As discussed below, a long jump to a forward label which
  123.           could be short will generate a comment.  MACROS.MLB needs
  124.           something like MACRO_EXPANSION_CONTROL to reset itself
  125.           afterwards.
  126.  
  127.           B.  OUT_UNNECESSARY_LONG_COMMENTS - Closing summary macro
  128.  
  129.                Use the macro OUT_UNNECESSARY_LONG_COMMENTS, which has no
  130.           arguments, at the end of any file which uses any of the macros
  131.           described in Section III, JUMPS TO EXPLICIT LABELS or Section IV,
  132.           STRCTURED MACROS with a LONG argument.  It will add a comment if
  133.           there are any unnecessary long forward jumps and also print a
  134.           message to that effect on the screen.  It does nothing if there
  135.           are none.
  136.  
  137.                Strictly speaking, you only need to use 
  138.           OUT_UNNECESSARY_LONG_COMMENTS if you have a forward long jump. 
  139.           Rather than worry about whether a structured macro is forward or
  140.           backward, it is easier to use it in any case where it might come
  141.           into play.
  142.  
  143.           C.  BLANK MACRO ARGUMENTS
  144.  
  145.                Indicate that all arguments of a macro are blank by not
  146.           entering a macro list.  Indicate that the last argument of a
  147.           macro is blank by ending the argument list with the last
  148.           non-blank argument.  Indicate that the first argument of a macro
  149.           is blank by starting the macro list with a comma.  Indicate that
  150.           an internal argument of a macro is blank by entering just a comma
  151.           following the preceding comma.
  152.  
  153.  
  154.  
  155.  
  156.  
  157.           Documentation for MACROS.MLB                               Page 4
  158.  
  159.  
  160.              CONVENTIONS, OPENING MACROS AND CLOSING MACROS (Continued)
  161.  
  162.           D.  CONVENTIONS IN THIS DOCUMENTATION
  163.  
  164.                CONDITION-1 is a completion to any conditional jump J
  165.           instruction except JCXZ.  Its legal values are:
  166.                     A, AE, B, BE, C, E, G, GE, L, LE, NA, NAE, NB, NBE, NC,
  167.                NE, NG, NGE, NL, NLE, NO, NP, NS, NZ, O, P, PE, PO, S, Z.
  168.  
  169.                CONDITION-2 is a completion to any condition jump J
  170.           instruction which tests flags affected by an OR instruction
  171.           except JCXZ.  The values for which it gives a choice are:
  172.                     BE, E, G, GE, L, LE, NA, NE, NG, NGE, NL, NLE, NP, NS,
  173.                NZ, P, PE, PO, S, Z.
  174.           It is always true, so probably not useful, for:
  175.                     A, AE, NB, NBE, NC, NO.
  176.           It is always false, so probably not useful, for:
  177.                     B, C, O, NAE.
  178.  
  179.                CONDITION-3 is a completion to any LOOP instruction.  Its
  180.           legal values are:
  181.                     blank, E, NE, NZ, Z.
  182.  
  183.                VAR1, CONDITION, VAR2 has two meanings.  If VAR2 is blank,
  184.           it means, "AND VAR1, VAR1", then jump on CONDITION-2.  Since the
  185.           8086 does not allow "AND mem, mem", this option only works if
  186.           VAR1 is a register.  If VAR2 is not blank, it means,
  187.           "CMP VAR1, VAR2", then jump on CONDITION-1.  Since the 8086 does
  188.           not allow "CMP mem1, mem2", this option requires that either VAR1
  189.           or VAR2 be either a register or an immediate variable.  Most of
  190.           the macros have a form which jumps on a condition which is
  191.           already set.  In those cases, you are free to set it by any
  192.           operation you want.
  193.  
  194.                LONG forces MASM to compile a long forward jump if it is not
  195.           blank.  It is always the last argument.  Anything in this
  196.           position will do, but the word "long" could clarify your meaning. 
  197.           Incidentally, MACROS.MLB ignores LONG for a backward jump.
  198.  
  199.  
  200.  
  201.  
  202.  
  203.  
  204.           Documentation for MACROS.MLB                               Page 5
  205.  
  206.  
  207.           III.     A STRATEGY TO MINIMIZE THE NUMBER OF LONG JUMPS
  208.  
  209.                MASM can determine whether a backward jump is long or short
  210.           on pass 1, but it can't do the same thing for forward jumps.  The
  211.           LONG argument is the way the macros below respond to this
  212.           problem.
  213.  
  214.                One general strategy which you coud follow to assure
  215.           yourself that there are no unnecessary long jumps is:
  216.  
  217.                          Compile with no LONG arguments.
  218.  
  219.                          If there are any "Relative jump out of range"
  220.                     error messages, add a LONG argument to those macros and
  221.                     compile again.
  222.  
  223.                          Repeat the last step until there are no "Relative
  224.                     jump out of range" error messages.
  225.  
  226.                Since each LONG adds some bytes, it is possible that adding
  227.           a LONG argument will spread out another forward jump so it must
  228.           be long.  You can cook up some very intertwined examples which
  229.           would take many cycles to clear up, but usually there shouldn't
  230.           be too many recyclings.
  231.  
  232.                If you are sure that a forward jump will exceed 127 bytes,
  233.           you could use a LONG argument immediately.  If you are wrong, you
  234.           will get a comment which tells you that that particular jump
  235.           doesn't need to be long.  If this happens, I suggest that you use
  236.           the pure general strategy  which I outlined above.
  237.  
  238.  
  239.  
  240.  
  241.  
  242.  
  243.  
  244.           Documentation for MACROS.MLB                               Page 6
  245.  
  246.  
  247.           IV.                 JUMPS TO EXPLICIT LABELS
  248.  
  249.           A.  GENERAL
  250.  
  251.                MASM can determine whether a backward jump is long or short
  252.           on pass 1.  It can't do the same thing for a forward jump, but it
  253.           can tell on pass 2 if a long forward jump could have been short. 
  254.           These macros take advantage of those abilities.
  255.  
  256.                Each of them jump or loop to the argument target_label.  For
  257.           backward jumps, each of them either issues a short jump or else
  258.           one or more instructions which give the same conditional effect
  259.           if any and issue a long jump.  
  260.  
  261.                For forward jumps, they all use the variable LONG, which I
  262.           described in Section II-D above.  MASM will flag short forward
  263.           jumps which should have been long as an error 53, "Relative jump
  264.           out of range."  Each of these macros write a comment, "******
  265.           This jump doesn't need to be LONG ******" for a long forward jump
  266.           which could have been short.
  267.  
  268.                See Section III above for a strategy which minimizes the
  269.           number of long jumps.
  270.  
  271.           B.  LJMP TARGET_LABEL, LONG - Unconditional jump to TARGET_LABEL.
  272.  
  273.           C.  LCJMP CONDITION-1, TARGET_LABEL, LONG - Conditional jump to
  274.           TARGET_LABEL.
  275.  
  276.                CONDITION-1 is the conditional part of any J? operation
  277.           except JCXZ.  See Section II-D above for a complete list.
  278.  
  279.           D.  LJCXZ TARGET_LABEL, LONG - Jump to TARGET_LABEL if register
  280.           CX is zero.
  281.  
  282.           E.  LLOOP CONDITION-3, TARGET_LABEL, LONG - Conditional and
  283.           unconditional loops.
  284.  
  285.                Use "LLOOP ,TARGET_LABEL, LONG" for an unconditional loop. 
  286.           See Section II-C for a discussion of blank macro arguments.  
  287.           Otherwise, E, NE, NZ, Z are legal values for CONDITION-3.
  288.  
  289.  
  290.  
  291.  
  292.  
  293.  
  294.           Documentation for MACROS.MLB                               Page 7
  295.  
  296.  
  297.  
  298.           V.                      STRUCTURED MACROS
  299.  
  300.           A.  GENERAL
  301.  
  302.                Structured macros are combinations of macros which produce
  303.           the effects of structured programming.  They generate their own
  304.           labels, which have the form L?n, where n is a number which is
  305.           more or less sequential.  They can be nested almost indefinitely. 
  306.  
  307.                They use all of the long and short features of jumps to
  308.           explicit labels discussed in Section III-A above.  If a component
  309.           macro includes a forward jump, its arguments will terminate with
  310.           LONG.  See Section III above for a strategy which minimizes the
  311.           number of long jumps.
  312.  
  313.                See Section II-D for descriptions of arguments not
  314.           explicitly described with the structured macro.
  315.  
  316.                The list of structured macros below is probably not
  317.           complete.  You can use the source code to build other
  318.           combinations to fit your particular needs.
  319.  
  320.  
  321.  
  322.  
  323.  
  324.  
  325.  
  326.           Documentation for MACROS.MLB                               Page 8
  327.  
  328.  
  329.                              STRUCTURED MACROS (Continued)
  330.  
  331.           B.  Jump to the beginning or the end of an "enclosing block"
  332.  
  333.                I will define the term "enclosing block" to mean a pair of
  334.           macros which establish internal labels at the start of the first
  335.           one and after the second one.  Several of the macro combinations
  336.           discussed below form enclosing blocks.  The following macros will
  337.           jump to the beginning or past the end of any of them:
  338.  
  339.                     XNEXT     LONG      ; Unconditionally jump to the
  340.                                         ; beginning of the block
  341.  
  342.                     XCNEXT    VAR1, CONDITION, VAR2, LONG
  343.                                         ; Set condition then conditionally
  344.                                         ; jump to the beginning of the
  345.                                         ; block
  346.  
  347.                     XCNEXTC   CONDITION-1, LONG
  348.                                         ; Jump to the beginning of the
  349.                                         ; block based on the condition when
  350.                                         ; you invoke the macro
  351.  
  352.                     XEXIT     LONG      ; Unconditionally jump to beyond
  353.                                         ; the end of the block
  354.  
  355.                     XCEXIT    VAR1, CONDITION, VAR2, LONG
  356.                                         ; Set condition then conditionally
  357.                                         ; jump to beyond the end of the
  358.                                         ; block
  359.  
  360.                     XCEXITC   CONDITION-1 LONG
  361.                                         ; Jump to beyond the end of the
  362.                                         ; block based on the condition when
  363.                                         ; you invoke the macro
  364.  
  365.                You can use these macros outside of an enclosing block.  The
  366.           NEXT macros will look for the internal label with the next
  367.           sequential number, and the EXIT macros will look for the internal
  368.           label with the current sequential number plus 2.  There are
  369.           enough possibilities so that their effect is somewhat
  370.           unpredicable.  I suggest a jump to an explicit label instead.
  371.  
  372.                If these macros are used inside of an enclosing block,
  373.           XEXIT, XCEXIT and XCEXITC include forward jumps.
  374.  
  375.                Each section will say whether its macros form an enclosing
  376.           block.
  377.  
  378.  
  379.  
  380.  
  381.  
  382.  
  383.  
  384.           Documentation for MACROS.MLB                               Page 9
  385.  
  386.  
  387.                              STRUCTURED MACROS (Continued)
  388.  
  389.           C.  BEGIN and END
  390.  
  391.                     XBEGIN
  392.                     body
  393.                     XEND
  394.  
  395.                BEGIN and END form an enclosing block with no other effects.
  396.  
  397.           D.  IF and IF - ELSE with one condition
  398.  
  399.                     XIF       VAR1, CONDITION, VAR2, LONG
  400.                     body
  401.                     XENDIF
  402.  
  403.                If you want to set CONDITION-1 before you invoke XIF,
  404.           replace the XIF line with
  405.                     XIFC      CONDITION-1, LONG
  406.  
  407.                Each of these forms allows an optional ELSE clause.  For
  408.           example, the first form becomes:
  409.  
  410.                     XIF       VAR1, CONDITION, VAR2, LONG
  411.                     body-1
  412.                     XELSE     LONG
  413.                     body-2
  414.                     XENDIF
  415.  
  416.                XIF, XIFC and XELSE each include forward jumps.
  417.  
  418.                XIF and XENDIF form an enclosing block as long as there is
  419.           no XELSE between them.  If there is an XELSE between them, they
  420.           do not form and enclosing block.  For this reason, it is probably
  421.           safer to use XBEGIN and XEND around body-1 and/or body-2 if you
  422.           want any form of XNEXT or XEXIT.
  423.  
  424.  
  425.  
  426.  
  427.  
  428.  
  429.  
  430.           Documentation for MACROS.MLB                              Page 10
  431.  
  432.  
  433.                              STRUCTURED MACROS (Continued)
  434.  
  435.           E.  IF and IF - ELSE with multiple AND conditions
  436.  
  437.                     XIF       VAR1, CONDITION, VAR2, LONG
  438.                     XANDIF    VAR1, CONDITION, VAR2, LONG
  439.                                         ; The two invocations should have
  440.                                         ; at least one of VAR1, CONDITION
  441.                                         ; and VAR2 different to be useful.
  442.                     body
  443.                     XENDIF
  444.  
  445.                You must first use exactly one XIF.  You can then use more
  446.           than one XANDIF.
  447.  
  448.                You can use both XIFC and XELSE as above in this form.  In
  449.           addition, you can set CONDITION-1 for an XANDIF and replace it
  450.           with
  451.                     XANDIFC   CONDITION-1, LONG
  452.  
  453.                XANDIF and XANDIFC each include forward jumps.
  454.  
  455.                XIF or XIFC and XENDIF form an enclosing block as long as
  456.           there is no XELSE between them.  If there is an XELSE between
  457.           them, they do not form and enclosing block.  For this reason, it
  458.           is probably safer to use XBEGIN and XEND around body-1 and/or
  459.           body-2 if you want any form of XNEXT or XEXIT.
  460.  
  461.  
  462.  
  463.  
  464.  
  465.  
  466.  
  467.           Documentation for MACROS.MLB                              Page 11
  468.  
  469.  
  470.                              STRUCTURED MACROS (Continued)
  471.  
  472.           F.  Repetition for a count
  473.  
  474.                Enter with CX set to the maximum number of times to repeat.
  475.  
  476.                     XFOR      NOZERO, LONG
  477.                                         ; If NOZERO is blank, skip the body
  478.                                         ; of the loop if CX starts as zero. 
  479.                                         ; If it exists, always repeat at
  480.                                         ; least once.
  481.                     body
  482.                     XDEC      CONDITION-3
  483.                                         ; End of loop
  484.  
  485.  
  486.                The value of NOZERO doesn't matter.  For documentation, you
  487.           might consider using nozero.
  488.  
  489.                LONG is only useful if NOZERO is blank.  The three useful
  490.           configurations of the FOR line are:
  491.                     FOR
  492.                     FOR  nozero
  493.                     FOR  , long
  494.  
  495.                CONDITION-3 can be blank for an unconditional loop or E, NZ,
  496.           NE or Z for a conditional loop.  See Section II-D for more
  497.           information on CONDITION-3.
  498.  
  499.                If NOZERO is blank, XFOR contains a forward jump.  If it is
  500.           not blank, XFOR does not contain a forward jump.
  501.  
  502.                XFOR and XDEC form an enclosing block.  XNEXT does not
  503.           change the number of repetitions.  If you want to bypass part of
  504.           the processing for this repetition but keep on counting, enclose
  505.           body with XBEGIN and XEND and then use XEXIT.
  506.  
  507.  
  508.  
  509.  
  510.  
  511.  
  512.  
  513.           Documentation for MACROS.MLB                              Page 12
  514.  
  515.  
  516.                              STRUCTURED MACROS (Continued)
  517.  
  518.           G.  WHILE
  519.  
  520.                     XWHILE    VAR1, CONDITION, VAR2, LONG
  521.                                         ; Terminate loop if CONDITION-1
  522.                     body
  523.                     XENDLP              ; End this pass through the loop
  524.  
  525.  
  526.                If you want to initialize CONDITION-1 before entering and
  527.           set it in body for the next pass through the loop, replace the
  528.           XWHILE line with 
  529.                     XWHILEC   CONDITION-1, LONG
  530.                                         ; Terminate loop if CONDTION-1
  531.  
  532.                XEXIT and XEXITC include forward jumps.
  533.  
  534.                XWHILE or XWHILEC and XENDLP form an enclosing block.
  535.  
  536.           H.  REPEAT UNTIL
  537.  
  538.                     XREPEAT             ; Start of loop
  539.                     body
  540.                     XUNTIL    VAR1, CONDITION, VAR2
  541.                                         ; End this pass through the loop
  542.  
  543.                If you want to set CONDITION-1 in body, replace the XUNTIL
  544.           line with 
  545.                     XUNTILC CONDITION-1 ; End this pass through the loop
  546.  
  547.                XREPEAT and XUNTIL or XUNTILC form an enclosing block. 
  548.           XNEXT does not test CONDITION-1.  If you want to bypass part of
  549.           the processing for this repetition but still test, enclose body
  550.           with XBEGIN and XEND and then use XEXIT.
  551.  
  552.           I.  REPEAT FOREVER
  553.  
  554.                     XLOOP
  555.                     body
  556.                     XENDLP
  557.  
  558.                body should include some form of XEXIT.
  559.  
  560.                XLOOP and XENDLP form an enclosing block.
  561.  
  562.                NOTE:  XLOOP is a synonym for XREPEAT.
  563.  
  564.  
  565.  
  566.  
  567.  
  568.  
  569.           Documentation for MACROS.MLB                              Page 13
  570.  
  571.  
  572.  
  573.           VI.                        OTHER MACROS
  574.  
  575.           A.  Multiple PUSH and POP
  576.  
  577.                PUSH_REGISTER  <REGISTER LIST> pushes the list of registers
  578.           contained in REGISTER LIST on the program stack and saves what it
  579.           has done for POP_REGISTER.
  580.  
  581.                POP_REGISTER pops the registers saved by PUSH_REGISTER in
  582.           the proper order.
  583.  
  584.                PUSHM <LIST> pushes the registers and memory locations
  585.           contained in LIST on the program stack in the same order as LIST.
  586.  
  587.                POPM <LIST> pops the registers and memory locations
  588.           contained in LIST from the program stack in the same order as
  589.           LIST.  If it is used with PUSHM, the two LIST's should be in
  590.           reversed order.
  591.  
  592.                The angle brackets in PUSH_REGISTER, PUSHM and POPM are
  593.           required.
  594.  
  595.           B.  Show the state of the Zero Flag in AL
  596.  
  597.                GETZ sets AL to TRUE if the Zero Flag is set and to FALSE if
  598.           it is not set.
  599.  
  600.                GETNZ sets AL to TRUE if the Zero Flag is not set and to
  601.           FALSE if it is set.
  602.  
  603.  
  604.           C.  NOTZ - Toggle the Zero Flag
  605.  
  606.           D.  Call procedures which use a string whose OFFSET is in either
  607.           BX or DX
  608.  
  609.                CALLSTR   ROUTINE, STRING
  610.           where
  611.                     ROUTINE is the name of the procedure to call.
  612.                     STRING is the name of a string whose OFFSET should go
  613.                into register DX.
  614.  
  615.                GETCALL   ROUTINE, STRING
  616.           where
  617.                     ROUTINE is the name of the procedure to call.
  618.                     STRING is the name of a string whose OFFSET should go
  619.                into register BX.
  620.  
  621.  
  622.  
  623.  
  624.  
  625.  
  626.           Documentation for MACROS.MLB                              Page 14
  627.  
  628.  
  629.                                OTHER MACROS (Continued)
  630.  
  631.  
  632.           E.  Call a procedure which uses a File Control Block
  633.  
  634.                FCBCALL        ROUTINE, FCB, ERRORRTN
  635.           where
  636.                     ROUTINE is the name of the procedure to call.  It
  637.                should set the Zero Flag if there is an error.
  638.                     FCB is the name of the File Control Block.
  639.                     ERRORRTN is the optional name of an error procedure
  640.                which the program will call if the Zero Flag is set.
  641.  
  642.  
  643.